package com.lifeverse.controller;

import com.lifeverse.common.ApiResponse;
import com.lifeverse.entity.HealthCheck;
import com.lifeverse.entity.ServiceDiscovery;
import com.lifeverse.entity.SystemAlert;
import com.lifeverse.entity.enums.AlertSeverity;
import com.lifeverse.entity.enums.AlertStatus;
import com.lifeverse.service.AlertService;
import com.lifeverse.service.HealthCheckService;
import com.lifeverse.service.ServiceDiscoveryService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.Optional;

/**
 * 监控控制器
 */
@RestController
@RequestMapping("/api/monitoring")
@RequiredArgsConstructor
@Slf4j
@Tag(name = "监控管理", description = "系统监控和告警管理接口")
public class MonitoringController {

    private final AlertService alertService;
    private final HealthCheckService healthCheckService;
    private final ServiceDiscoveryService serviceDiscoveryService;

    // ==================== 告警管理 ====================

    @Operation(summary = "获取活跃告警", description = "获取所有活跃状态的告警")
    @GetMapping("/alerts/active")
    public ResponseEntity<ApiResponse<List<SystemAlert>>> getActiveAlerts() {
        List<SystemAlert> alerts = alertService.getActiveAlerts();
        return ResponseEntity.ok(ApiResponse.success(alerts));
    }

    @Operation(summary = "获取高优先级告警", description = "获取高优先级的活跃告警")
    @GetMapping("/alerts/high-priority")
    public ResponseEntity<ApiResponse<List<SystemAlert>>> getHighPriorityAlerts() {
        List<SystemAlert> alerts = alertService.getHighPriorityActiveAlerts();
        return ResponseEntity.ok(ApiResponse.success(alerts));
    }

    @Operation(summary = "查询告警", description = "根据条件查询告警")
    @GetMapping("/alerts")
    public ResponseEntity<ApiResponse<Page<SystemAlert>>> getAlerts(
            @Parameter(description = "告警状态") @RequestParam(required = false) AlertStatus status,
            @Parameter(description = "严重程度") @RequestParam(required = false) AlertSeverity severity,
            @Parameter(description = "告警源") @RequestParam(required = false) String source,
            @Parameter(description = "开始时间") @RequestParam(required = false) 
            @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime startTime,
            @Parameter(description = "结束时间") @RequestParam(required = false) 
            @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime endTime,
            Pageable pageable) {
        
        if (startTime == null) {
            startTime = LocalDateTime.now().minusDays(7);
        }
        if (endTime == null) {
            endTime = LocalDateTime.now();
        }
        
        Page<SystemAlert> alerts = alertService.getAlertsByConditions(
                status, severity, source, startTime, endTime, pageable);
        return ResponseEntity.ok(ApiResponse.success(alerts));
    }

    @Operation(summary = "确认告警", description = "确认指定的告警")
    @PostMapping("/alerts/{alertId}/acknowledge")
    public ResponseEntity<ApiResponse<SystemAlert>> acknowledgeAlert(
            @Parameter(description = "告警ID") @PathVariable Long alertId,
            @Parameter(description = "确认人") @RequestParam String acknowledgedBy) {
        
        SystemAlert alert = alertService.acknowledgeAlert(alertId, acknowledgedBy);
        return ResponseEntity.ok(ApiResponse.success(alert));
    }

    @Operation(summary = "解决告警", description = "解决指定的告警")
    @PostMapping("/alerts/{alertId}/resolve")
    public ResponseEntity<ApiResponse<SystemAlert>> resolveAlert(
            @Parameter(description = "告警ID") @PathVariable Long alertId,
            @Parameter(description = "解决人") @RequestParam String resolvedBy) {
        
        SystemAlert alert = alertService.resolveAlert(alertId, resolvedBy);
        return ResponseEntity.ok(ApiResponse.success(alert));
    }

    @Operation(summary = "批量处理告警", description = "批量确认或解决告警")
    @PostMapping("/alerts/batch")
    public ResponseEntity<ApiResponse<String>> batchProcessAlerts(
            @Parameter(description = "告警ID列表") @RequestParam List<Long> alertIds,
            @Parameter(description = "操作类型") @RequestParam String action,
            @Parameter(description = "操作人") @RequestParam String operator) {
        
        alertService.batchProcessAlerts(alertIds, action, operator);
        return ResponseEntity.ok(ApiResponse.success("批量处理完成"));
    }

    @Operation(summary = "获取告警统计", description = "获取告警统计信息")
    @GetMapping("/alerts/statistics")
    public ResponseEntity<ApiResponse<Map<String, Object>>> getAlertStatistics() {
        Map<String, Object> statistics = alertService.getAlertStatistics();
        return ResponseEntity.ok(ApiResponse.success(statistics));
    }

    @Operation(summary = "获取长时间未解决的告警", description = "获取超过指定时间未解决的告警")
    @GetMapping("/alerts/long-running")
    public ResponseEntity<ApiResponse<List<SystemAlert>>> getLongRunningAlerts(
            @Parameter(description = "小时阈值") @RequestParam(defaultValue = "24") int hoursThreshold) {
        
        List<SystemAlert> alerts = alertService.getLongRunningAlerts(hoursThreshold);
        return ResponseEntity.ok(ApiResponse.success(alerts));
    }

    // ==================== 健康检查 ====================

    @Operation(summary = "注册健康检查", description = "注册新的健康检查")
    @PostMapping("/health-checks")
    public ResponseEntity<ApiResponse<HealthCheck>> registerHealthCheck(
            @Parameter(description = "服务名称") @RequestParam String serviceName,
            @Parameter(description = "检查名称") @RequestParam String checkName,
            @Parameter(description = "检查端点") @RequestParam String endpoint,
            @Parameter(description = "检查间隔(秒)") @RequestParam(required = false) Integer intervalSeconds,
            @Parameter(description = "超时时间(秒)") @RequestParam(required = false) Integer timeoutSeconds) {
        
        HealthCheck healthCheck = healthCheckService.registerHealthCheck(
                serviceName, checkName, endpoint, intervalSeconds, timeoutSeconds);
        return ResponseEntity.ok(ApiResponse.success(healthCheck));
    }

    @Operation(summary = "执行健康检查", description = "手动执行指定的健康检查")
    @PostMapping("/health-checks/{healthCheckId}/check")
    public ResponseEntity<ApiResponse<String>> performHealthCheck(
            @Parameter(description = "健康检查ID") @PathVariable Long healthCheckId) {
        
        healthCheckService.performHealthCheck(healthCheckId);
        return ResponseEntity.ok(ApiResponse.success("健康检查已启动"));
    }

    @Operation(summary = "获取服务健康状态", description = "获取指定服务的健康状态")
    @GetMapping("/health-checks/service/{serviceName}")
    public ResponseEntity<ApiResponse<List<HealthCheck>>> getServiceHealthStatus(
            @Parameter(description = "服务名称") @PathVariable String serviceName) {
        
        List<HealthCheck> healthChecks = healthCheckService.getServiceHealthStatus(serviceName);
        return ResponseEntity.ok(ApiResponse.success(healthChecks));
    }

    @Operation(summary = "获取不健康的服务", description = "获取所有不健康的服务")
    @GetMapping("/health-checks/unhealthy")
    public ResponseEntity<ApiResponse<List<HealthCheck>>> getUnhealthyServices() {
        List<HealthCheck> unhealthyServices = healthCheckService.getUnhealthyServices();
        return ResponseEntity.ok(ApiResponse.success(unhealthyServices));
    }

    @Operation(summary = "获取健康检查统计", description = "获取健康检查统计信息")
    @GetMapping("/health-checks/statistics")
    public ResponseEntity<ApiResponse<Map<String, Object>>> getHealthStatistics() {
        Map<String, Object> statistics = healthCheckService.getHealthStatistics();
        return ResponseEntity.ok(ApiResponse.success(statistics));
    }

    @Operation(summary = "启用/禁用健康检查", description = "启用或禁用指定的健康检查")
    @PutMapping("/health-checks/{healthCheckId}/toggle")
    public ResponseEntity<ApiResponse<HealthCheck>> toggleHealthCheck(
            @Parameter(description = "健康检查ID") @PathVariable Long healthCheckId,
            @Parameter(description = "是否启用") @RequestParam boolean enabled) {
        
        HealthCheck healthCheck = healthCheckService.toggleHealthCheck(healthCheckId, enabled);
        return ResponseEntity.ok(ApiResponse.success(healthCheck));
    }

    @Operation(summary = "删除健康检查", description = "删除指定的健康检查")
    @DeleteMapping("/health-checks/{healthCheckId}")
    public ResponseEntity<ApiResponse<String>> deleteHealthCheck(
            @Parameter(description = "健康检查ID") @PathVariable Long healthCheckId) {
        
        healthCheckService.deleteHealthCheck(healthCheckId);
        return ResponseEntity.ok(ApiResponse.success("健康检查已删除"));
    }

    @Operation(summary = "获取服务健康趋势", description = "获取指定服务的健康趋势")
    @GetMapping("/health-checks/trend/service/{serviceName}")
    public ResponseEntity<ApiResponse<List<Object[]>>> getServiceHealthTrend(
            @Parameter(description = "服务名称") @PathVariable String serviceName,
            @Parameter(description = "天数") @RequestParam(defaultValue = "7") int days) {
        
        List<Object[]> trend = healthCheckService.getServiceHealthTrend(serviceName, days);
        return ResponseEntity.ok(ApiResponse.success(trend));
    }

    @Operation(summary = "获取整体健康趋势", description = "获取系统整体健康趋势")
    @GetMapping("/health-checks/trend/overall")
    public ResponseEntity<ApiResponse<List<Object[]>>> getOverallHealthTrend(
            @Parameter(description = "天数") @RequestParam(defaultValue = "7") int days) {
        
        List<Object[]> trend = healthCheckService.getOverallHealthTrend(days);
        return ResponseEntity.ok(ApiResponse.success(trend));
    }

    // ==================== 服务发现 ====================

    @Operation(summary = "注册服务", description = "注册新的服务实例")
    @PostMapping("/services/register")
    public ResponseEntity<ApiResponse<ServiceDiscovery>> registerService(
            @RequestBody ServiceRegistrationRequest request) {
        
        ServiceDiscovery service = serviceDiscoveryService.registerService(
                request.getServiceName(), request.getInstanceId(), request.getHost(),
                request.getPort(), request.getVersion(), request.getEnvironment(),
                request.getMetadata(), request.getTags());
        
        return ResponseEntity.ok(ApiResponse.success(service));
    }

    @Operation(summary = "注销服务", description = "注销服务实例")
    @PostMapping("/services/{instanceId}/deregister")
    public ResponseEntity<ApiResponse<String>> deregisterService(
            @Parameter(description = "实例ID") @PathVariable String instanceId) {
        
        serviceDiscoveryService.deregisterService(instanceId);
        return ResponseEntity.ok(ApiResponse.success("服务已注销"));
    }

    @Operation(summary = "更新心跳", description = "更新服务实例心跳")
    @PostMapping("/services/{instanceId}/heartbeat")
    public ResponseEntity<ApiResponse<String>> updateHeartbeat(
            @Parameter(description = "实例ID") @PathVariable String instanceId) {
        
        serviceDiscoveryService.updateHeartbeat(instanceId);
        return ResponseEntity.ok(ApiResponse.success("心跳已更新"));
    }

    @Operation(summary = "发现服务", description = "发现指定服务的所有可用实例")
    @GetMapping("/services/discover/{serviceName}")
    public ResponseEntity<ApiResponse<List<ServiceDiscovery>>> discoverServices(
            @Parameter(description = "服务名称") @PathVariable String serviceName) {
        
        List<ServiceDiscovery> services = serviceDiscoveryService.discoverServices(serviceName);
        return ResponseEntity.ok(ApiResponse.success(services));
    }

    @Operation(summary = "选择服务实例", description = "根据负载均衡策略选择服务实例")
    @GetMapping("/services/select/{serviceName}")
    public ResponseEntity<ApiResponse<ServiceDiscovery>> selectServiceInstance(
            @Parameter(description = "服务名称") @PathVariable String serviceName,
            @Parameter(description = "负载均衡策略") @RequestParam(defaultValue = "random") String strategy) {
        
        Optional<ServiceDiscovery> service = serviceDiscoveryService.selectServiceInstance(serviceName, strategy);
        if (service.isPresent()) {
            return ResponseEntity.ok(ApiResponse.success(service.get()));
        } else {
            return ResponseEntity.ok(ApiResponse.error("没有可用的服务实例"));
        }
    }

    @Operation(summary = "获取所有可用服务", description = "获取所有可用的服务实例")
    @GetMapping("/services/available")
    public ResponseEntity<ApiResponse<List<ServiceDiscovery>>> getAllAvailableServices() {
        List<ServiceDiscovery> services = serviceDiscoveryService.getAllAvailableServices();
        return ResponseEntity.ok(ApiResponse.success(services));
    }

    @Operation(summary = "根据标签查询服务", description = "根据标签查询服务实例")
    @GetMapping("/services/by-tag/{tag}")
    public ResponseEntity<ApiResponse<List<ServiceDiscovery>>> findServicesByTag(
            @Parameter(description = "标签") @PathVariable String tag) {
        
        List<ServiceDiscovery> services = serviceDiscoveryService.findServicesByTag(tag);
        return ResponseEntity.ok(ApiResponse.success(services));
    }

    @Operation(summary = "根据环境查询服务", description = "根据环境查询服务实例")
    @GetMapping("/services/by-environment/{environment}")
    public ResponseEntity<ApiResponse<List<ServiceDiscovery>>> findServicesByEnvironment(
            @Parameter(description = "环境") @PathVariable String environment) {
        
        List<ServiceDiscovery> services = serviceDiscoveryService.findServicesByEnvironment(environment);
        return ResponseEntity.ok(ApiResponse.success(services));
    }

    @Operation(summary = "获取服务统计", description = "获取服务发现统计信息")
    @GetMapping("/services/statistics")
    public ResponseEntity<ApiResponse<Map<String, Object>>> getServiceStatistics() {
        Map<String, Object> statistics = serviceDiscoveryService.getServiceStatistics();
        return ResponseEntity.ok(ApiResponse.success(statistics));
    }

    @Operation(summary = "获取服务版本", description = "获取指定服务的所有版本")
    @GetMapping("/services/{serviceName}/versions")
    public ResponseEntity<ApiResponse<List<String>>> getServiceVersions(
            @Parameter(description = "服务名称") @PathVariable String serviceName) {
        
        List<String> versions = serviceDiscoveryService.getServiceVersions(serviceName);
        return ResponseEntity.ok(ApiResponse.success(versions));
    }

    @Operation(summary = "更新服务权重", description = "更新服务实例的权重")
    @PutMapping("/services/{instanceId}/weight")
    public ResponseEntity<ApiResponse<ServiceDiscovery>> updateServiceWeight(
            @Parameter(description = "实例ID") @PathVariable String instanceId,
            @Parameter(description = "权重") @RequestParam Integer weight) {
        
        ServiceDiscovery service = serviceDiscoveryService.updateServiceWeight(instanceId, weight);
        return ResponseEntity.ok(ApiResponse.success(service));
    }

    @Operation(summary = "获取注册趋势", description = "获取服务注册趋势")
    @GetMapping("/services/registration-trend")
    public ResponseEntity<ApiResponse<List<Object[]>>> getRegistrationTrend(
            @Parameter(description = "天数") @RequestParam(defaultValue = "30") int days) {
        
        List<Object[]> trend = serviceDiscoveryService.getRegistrationTrend(days);
        return ResponseEntity.ok(ApiResponse.success(trend));
    }

    // ==================== 数据传输对象 ====================

    public static class ServiceRegistrationRequest {
        private String serviceName;
        private String instanceId;
        private String host;
        private Integer port;
        private String version;
        private String environment;
        private Map<String, String> metadata;
        private java.util.Set<String> tags;

        // Getters and Setters
        public String getServiceName() { return serviceName; }
        public void setServiceName(String serviceName) { this.serviceName = serviceName; }
        
        public String getInstanceId() { return instanceId; }
        public void setInstanceId(String instanceId) { this.instanceId = instanceId; }
        
        public String getHost() { return host; }
        public void setHost(String host) { this.host = host; }
        
        public Integer getPort() { return port; }
        public void setPort(Integer port) { this.port = port; }
        
        public String getVersion() { return version; }
        public void setVersion(String version) { this.version = version; }
        
        public String getEnvironment() { return environment; }
        public void setEnvironment(String environment) { this.environment = environment; }
        
        public Map<String, String> getMetadata() { return metadata; }
        public void setMetadata(Map<String, String> metadata) { this.metadata = metadata; }
        
        public java.util.Set<String> getTags() { return tags; }
        public void setTags(java.util.Set<String> tags) { this.tags = tags; }
    }
}